# Author: Chris Moyer
from boto.sdb.persist import *
from boto.sdb.persist.object import *
from boto.sdb.persist.property import *
from boto.exception import *
from exceptions import *

class S3Object(SDBObject):
	"""
	Basic representation of an Object in this system
	this could either be a File or a Directory
	"""
	name = StringProperty()
	mode = PositiveIntegerProperty()
	uid = PositiveIntegerProperty()
	gid = PositiveIntegerProperty()
	size = PositiveIntegerProperty()
	atime = DateTimeProperty()
	mtime = DateTimeProperty()
	ctime = DateTimeProperty()
	parent = ObjectProperty(ref_class=SDBObject)

	def __init__(self, id=None, name=None, parent=None, mode=None, size=0, uid=0, gid=0):
		if(id != None):
			SDBObject.__init__(self, id)
		else:
			# We're allowed to have no parent only if
			# we're the root node
			if(name != "" and (parent == None or not isinstance(parent, S3Dir))):
				raise TypeError("Parent must be of type S3Dir")
			# We're not allowed to have duplicates, so lets make sure this file
			# insn't already in SDB
			try:
				S3Dir.find(name=name, parent=parent).next()
				raise DuplicateObject
			except(StopIteration):
				try:
					S3File.find(name=name, parent=parent).next()
					raise DuplicateObject
				except(StopIteration):
					pass
			SDBObject.__init__(self)
			self.name = name
			self.parent = parent
			self.mode = mode
			self.size = size
			self.uid = uid
			self.gid = gid
			self.save()

	@classmethod
	def get_by_path(cls, path):
		"""
		Get an S3Object by given path.

		@return S3Dir or S3File at this path (or None)
		"""
		if(path[-1] == "/"):
			path = path[:-1]
		path = path.split('/')
		dir = None
		for d in path[:-1]:
			try:
				dir = S3Dir.find(name=d, parent=dir).next()
			except(StopIteration):
				return None
		object = None
		try:
			object = S3File.find(name=path[-1], parent=dir).next()
		except(StopIteration):
			try:
				object = S3Dir.find(name=path[-1], parent=dir).next()
			except(StopIteration):
				return None
		return object



class S3File(S3Object):
	"""
	SubClass of S3Object that represents a FILE within
	this system.
	"""
	parent = ObjectProperty(ref_class=SDBObject) # TODO: Remove once bug in boto is fixed
	name = StringProperty() # TODO: Remove once bug in boto is fixed
	key = S3KeyProperty()

	def __init__(self, id=None, name=None, parent=None, mode=0100777, size=0, uid=0, gid=0):
		S3Object.__init__(self, id, name, parent, mode, size, uid, gid)

class S3Dir(S3Object):
	"""
	SubClass of S3Object that represents a DIRECTORY
	within this system.
	"""
	parent = ObjectProperty(ref_class=SDBObject) # TODO: Remove once bug in boto is fixed
	name = StringProperty() # TODO: Remove once bug in boto is fixed

	def __init__(self, id=None, name=None, parent=None, mode=040777, size=0, uid=0, gid=0):
		S3Object.__init__(self, id, name, parent, mode, size, uid, gid)


